<template>
  <div class="logs-panel">
    <div class="logs-header">
      <span>{{ title }}</span>
      <span class="logs-count">共 {{ logsCount }} 条</span>
      <div class="logs-actions">
        <slot name="actions">
          <el-button size="small" @click="handleClear" type="default">
            清空日志
          </el-button>
        </slot>
      </div>
    </div>
    <div class="logs-content" ref="logsContentRef" @wheel="handleWheel" @scroll="handleScroll">
      <div v-if="logs.length === 0" class="empty-logs">
        暂无日志
      </div>
      <div v-else class="logs-list">
        <div v-for="(log, index) in logs" :key="index" :class="['log-item', getLogClass(log.type)]">
          <span class="log-time">{{ formatTime(log.timestamp) }}</span>
          <span class="log-message">{{ log.message }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { nextTick, PropType, ref, watch } from 'vue'

// 定义日志类型
export interface LogEntry {
  type: 'info' | 'success' | 'warning' | 'error'
  message: string
  timestamp: number
}

// Props
const props = defineProps({
  logs: {
    type: Array as PropType<LogEntry[]>,
    required: true,
    default: () => []
  },
  title: {
    type: String,
    default: '运行日志'
  },
  autoScroll: {
    type: Boolean,
    default: true
  },
  maxLogs: {
    type: Number,
    default: 200
  }
})

// Emits
const emit = defineEmits<{
  clear: []
}>()

// Refs
const logsContentRef = ref<HTMLElement>()
const logsCount = ref(0)
const autoScrollEnabled = ref(true)

// 计算属性
const getLogClass = (type: string) => {
  switch (type) {
    case 'success': return 'log-success'
    case 'warning': return 'log-warning'
    case 'error': return 'log-error'
    default: return 'log-info'
  }
}

// 方法
const formatTime = (timestamp: number) => {
  return new Date(timestamp).toLocaleTimeString()
}

const handleClear = () => {
  emit('clear')
}

// 处理滚轮事件
const handleWheel = () => {
  autoScrollEnabled.value = false
}

// 处理滚动事件
const handleScroll = () => {
  if (!logsContentRef.value) return

  const { scrollTop, scrollHeight, clientHeight } = logsContentRef.value
  const isAtBottom = scrollHeight - scrollTop - clientHeight < 10

  // 只有用户主动滚动到底部时，才重新启用自动滚动
  if (isAtBottom) {
    autoScrollEnabled.value = true
  } else {
    autoScrollEnabled.value = false
  }
}

// 自动滚动到底部
const scrollToBottom = async () => {
  if (props.autoScroll && autoScrollEnabled.value && logsContentRef.value) {
    await nextTick()
    logsContentRef.value.scrollTop = logsContentRef.value.scrollHeight
  }
}

// 监听日志变化
watch(() => props.logs.length, () => {
  logsCount.value = props.logs.length
  scrollToBottom()
}, { immediate: true })

// 监听日志数组变化（用于深度监听）
watch(() => [...props.logs], scrollToBottom)
</script>

<style scoped>
.logs-panel {
  flex: 1;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.logs-header {
  padding: 8px 12px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 500;
}

.logs-count {
  font-size: 12px;
  color: #909399;
  margin-right: auto;
  margin-left: 16px;
}

.logs-actions {
  margin-left: auto;
}

.logs-content {
  flex: 1;
  overflow: auto;
  background-color: #fafafa;
  max-height: 400px;
}

.empty-logs {
  padding: 20px;
  text-align: center;
  color: #909399;
  font-size: 14px;
}

.logs-list {
  padding: 8px;
}

.log-item {
  padding: 4px 8px;
  margin-bottom: 4px;
  border-radius: 3px;
  font-size: 12px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  display: flex;
  align-items: flex-start;
  line-height: 1.4;
}

.log-time {
  color: #909399;
  margin-right: 8px;
  flex-shrink: 0;
  min-width: 70px;
}

.log-message {
  flex: 1;
  word-break: break-all;
}

.log-info {
  background-color: #f4f4f5;
  color: #909399;
}

.log-success {
  background-color: #f0f9ff;
  color: #67c23a;
}

.log-warning {
  background-color: #fdf6ec;
  color: #e6a23c;
}

.log-error {
  background-color: #fef0f0;
  color: #f56c6c;
}
</style>